<template><div><p>本文档最新版为 <a href="https://learnku.com/docs/laravel/10.x" target="_blank" rel="noopener noreferrer">10.x</a>，旧版本可能放弃维护，推荐阅读最新版！</p>
<h2 id="数据库-入门" tabindex="-1"><a class="header-anchor" href="#数据库-入门"><span>数据库：入门</span></a></h2>
<ul>
<li><a href="#introduction">简介</a>
<ul>
<li><a href="#configuration">配置</a></li>
<li><a href="#read-and-write-connections">读 &amp; 写连接</a></li>
<li><a href="#using-multiple-database-connections">使用多个数据库连接</a></li>
</ul>
</li>
<li><a href="#running-queries">运行原生 SQL 查询</a>
<ul>
<li><a href="#listening-for-query-events">查询事件监听</a></li>
</ul>
</li>
<li><a href="#database-transactions">数据库事务</a></li>
</ul>
<h2 id="简介" tabindex="-1"><a class="header-anchor" href="#简介"><span>简介</span></a></h2>
<p>Laravel 能使用原生 SQL、<a href="https://learnku.com/docs/laravel/5.5/queries" target="_blank" rel="noopener noreferrer">查询构造器</a> 和 <a href="https://learnku.com/docs/laravel/5.5/eloquent" target="_blank" rel="noopener noreferrer">Eloquent ORM</a> 在各种数据库后台与数据库进行非常简单的交互。当前 Laravel 支持四种数据库:</p>
<ul>
<li>MySQL</li>
<li>Postgres</li>
<li>SQLite</li>
<li>SQL Server</li>
</ul>
<h3 id="配置" tabindex="-1"><a class="header-anchor" href="#配置"><span>配置</span></a></h3>
<p>数据库的配置文件放置在 <code v-pre>config/database.php</code> 文件中，你可以在此定义所有的数据库连接，并指定默认使用的连接。此文件内提供了大部分 Laravel 能支持的数据库配置示例。</p>
<p>默认情况下，Laravel 的示例 <a href="https://learnku.com/docs/laravel/5.5/configuration#environment-configuration" target="_blank" rel="noopener noreferrer">环境配置</a> 使用了 <a href="https://learnku.com/docs/laravel/5.5/homestead" target="_blank" rel="noopener noreferrer">Laravel Homestead</a>（这是一种小型虚拟机，能让你很方便地在本地进行 Laravel 的开发）。你可以根据本地数据库的需要修改这个配置。</p>
<h4 id="sqlite-配置" tabindex="-1"><a class="header-anchor" href="#sqlite-配置"><span>SQLite 配置</span></a></h4>
<p>使用类似 <code v-pre>touch database/database.sqlite</code> 之类命令创建一个新的 SQLite 数据库之后，可以使用数据库的绝对路径配置环境变量来指向这个新创建的数据库:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token constant">DB_CONNECTION</span><span class="token operator">=</span>sqlite</span>
<span class="line"><span class="token constant">DB_DATABASE</span><span class="token operator">=</span><span class="token operator">/</span>absolute<span class="token operator">/</span>path<span class="token operator">/</span>to<span class="token operator">/</span>database<span class="token operator">.</span>sqlite</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="读-写连接" tabindex="-1"><a class="header-anchor" href="#读-写连接"><span>读 &amp; 写连接</span></a></h3>
<p>如果你想使一个数据库连接只用于 SELECT ，另一个连接用于 INSERT、UPDATE、和 DELETE。那么在 Laravel 中无论你使用的是原生查询、查询构造器，还是 Eloquent ORM，你都能很轻松地实现这个需求。</p>
<p>看看下面这个例子如何配置读/写连接：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'mysql'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'read'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'host'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'192.168.1.1'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'write'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'host'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'196.168.1.2'</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'sticky'</span>    <span class="token operator">=></span> <span class="token constant boolean">true</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'driver'</span>    <span class="token operator">=></span> <span class="token string single-quoted-string">'mysql'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'database'</span>  <span class="token operator">=></span> <span class="token string single-quoted-string">'database'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'username'</span>  <span class="token operator">=></span> <span class="token string single-quoted-string">'root'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'password'</span>  <span class="token operator">=></span> <span class="token string single-quoted-string">''</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'charset'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'utf8mb4'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'collation'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'utf8mb4_unicode_ci'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'prefix'</span>    <span class="token operator">=></span> <span class="token string single-quoted-string">''</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>要注意的是，上面的示例中的配置数组中添加了三个键 : <code v-pre>read</code> 和 <code v-pre>write</code> 和 <code v-pre>sticky</code>。<code v-pre>read</code> 和 <code v-pre>write</code> 键都包含了一个键的值为 <code v-pre>host</code> 的数组。<code v-pre>read</code> 和 <code v-pre>write</code> 连接的其余数据库配置都在 <code v-pre>mysql</code> 这个主数组里面。</p>
<p>如果你想要覆盖主数组中的值，则只需将配置的内容移入 <code v-pre>read</code> 和 <code v-pre>write</code> 数组中即可。因此，在这种情况下，<code v-pre>192.168.1.1</code> 将被用作「读取」连接的主机，而 <code v-pre>192.168.1.2</code> 将被用于「写入」连接。这两个连接会共享数据库的凭证、前缀、字符集，以及在主 <code v-pre>mysql</code> 数组中的选项。</p>
<p><strong><code v-pre>sticky</code> 选项</strong></p>
<p><code v-pre>sticky</code> 是一个 <em>可选的</em> 选项，它可用于立即读取在当前请求周期内已写入数据库的记录。</p>
<p>如果 <code v-pre>sticky</code> 选项被启用，并且在当前的请求周期内在数据库执行过「写入」操作，那么任何「读取」的操作都将使用「写入」连接。这可以确保在请求周期内写入的任何数据可以在同一请求期间立即从数据库读回。这个选项的作用取决于应用程序的需求。</p>
<h3 id="使用多个数据库连接" tabindex="-1"><a class="header-anchor" href="#使用多个数据库连接"><span>使用多个数据库连接</span></a></h3>
<p>使用多个连接时，可以通过 <code v-pre>DB</code> facade 上的 <code v-pre>connection</code> 方法访问每个连接。传递给 <code v-pre>connection</code> 方法的 <code v-pre>name</code> 应该对应于 <code v-pre>config/database.php</code> 配置信息文件中列出的连接之一：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$users</span> <span class="token operator">=</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">connection</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'foo'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">select</span><span class="token punctuation">(</span><span class="token operator">...</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>你也可以在连接实例上使用 <code v-pre>getPdo</code> 方法访问底层的原生 PDO 实例 ：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$pdo</span> <span class="token operator">=</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">connection</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">getPdo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="运行原生-sql-查询" tabindex="-1"><a class="header-anchor" href="#运行原生-sql-查询"><span>运行原生 SQL 查询</span></a></h2>
<p>配置好数据库连接后，可以使用 <code v-pre>DB</code> facade 运行查询。<code v-pre>DB</code> facade 为每种类型的查询提供了方法：<code v-pre>select</code>、<code v-pre>update</code>、<code v-pre>insert</code>、<code v-pre>delete</code> 和 <code v-pre>statement</code>。</p>
<h4 id="运行-select-查询" tabindex="-1"><a class="header-anchor" href="#运行-select-查询"><span>运行 Select 查询</span></a></h4>
<p>运行基础的查询语句，你可以使用 <code v-pre>DB</code> facade 上使用 <code v-pre>select</code> 方法:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Controllers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>DB</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Controllers<span class="token punctuation">\</span>Controller</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">UserController</span> <span class="token keyword">extends</span> <span class="token class-name">Controller</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 显示所有应用程序用户的列表</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name">Response</span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">index</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$users</span> <span class="token operator">=</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">select</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'select * from users where active = ?'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token keyword">return</span> <span class="token function">view</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'user.index'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'users'</span> <span class="token operator">=></span> <span class="token variable">$users</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>传递到 <code v-pre>select</code> 方法的第一个参数是一个原生的 SQL 查询，而第二个参数则是传递需要绑定到查询中的参数值。通常，这些是 <code v-pre>where</code> 子句约束的值。参数绑定提供了对防止 SQL 注入的保护。</p>
<p><code v-pre>select</code> 方法将始终返回一个数组。数组中的每个结果都是一个PHP <code v-pre>StdClass</code> 对象，可以像下面这样访问结果的值:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$users</span> <span class="token keyword">as</span> <span class="token variable">$user</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">echo</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="使用命名绑定" tabindex="-1"><a class="header-anchor" href="#使用命名绑定"><span>使用命名绑定</span></a></h4>
<p>除了使用 <code v-pre>?</code> 来表示参数绑定外，你也可以使用命名绑定来执行一个查询：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$results</span> <span class="token operator">=</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">select</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'select * from users where id = :id'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="运行插入语句" tabindex="-1"><a class="header-anchor" href="#运行插入语句"><span>运行插入语句</span></a></h4>
<p>可以在 <code v-pre>DB</code> facade 上使用 <code v-pre>insert</code> 方法来执行 <code v-pre>insert</code> 语句。与 <code v-pre>select</code> 一样，该方法将原生 SQL 查询作为其第一个参数，并将其绑定的数据作为第二个参数：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">insert</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'insert into users (id, name) values (?, ?)'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'Dayle'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="运行更新语句" tabindex="-1"><a class="header-anchor" href="#运行更新语句"><span>运行更新语句</span></a></h4>
<p><code v-pre>update</code> 方法用于更新数据库中的现有记录。该方法会返回受该语句影响的行数：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$affected</span> <span class="token operator">=</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">update</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update users set votes = 100 where name = ?'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'John'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="运行删除语句" tabindex="-1"><a class="header-anchor" href="#运行删除语句"><span>运行删除语句</span></a></h4>
<p><code v-pre>delete</code> 方法用于删除数据库中记录。与 <code v-pre>update</code> 一样，会返回受该语句影响的行数：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$deleted</span> <span class="token operator">=</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'delete from users'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="运行普通语句" tabindex="-1"><a class="header-anchor" href="#运行普通语句"><span>运行普通语句</span></a></h4>
<p>有些数据库语句不会返回任何值。对于这些语句，可以在 <code v-pre>DB</code> facade 上使用 <code v-pre>statement</code> 方法来操作：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">statement</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'drop table users'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="查询事件监听" tabindex="-1"><a class="header-anchor" href="#查询事件监听"><span>查询事件监听</span></a></h3>
<p>如果你想监控程序执行的每个 SQL 查询，你可以使用 <code v-pre>listen</code> 方法。这个方法对于记录查询或调试非常有用。你可以在 <a href="https://learnku.com/docs/laravel/5.5/providers" target="_blank" rel="noopener noreferrer">服务提供器</a> 中为你的查询注册监听器:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Providers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>DB</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>ServiceProvider</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">AppServiceProvider</span> <span class="token keyword">extends</span> <span class="token class-name">ServiceProvider</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 启动应用服务</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">listen</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$query</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">            <span class="token comment">// $query->sql</span></span>
<span class="line">            <span class="token comment">// $query->bindings</span></span>
<span class="line">            <span class="token comment">// $query->time</span></span>
<span class="line">        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 注册服务提供器</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">register</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token comment">//</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="数据库事务" tabindex="-1"><a class="header-anchor" href="#数据库事务"><span>数据库事务</span></a></h2>
<p>你可以在 <code v-pre>DB</code> facade 上使用 <code v-pre>transaction</code> 方法来运行数据库事务中的一组操作。如果在事务 <code v-pre>Closure</code> 中发生了异常，事务将自动回滚。而如果 <code v-pre>Closure</code> 成功执行，事务将自动被提交。也就是说，使用数据库事务，你就不需要在数据库语句执行发生异常时手动回滚或提交。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">transaction</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">table</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">update</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'votes'</span> <span class="token operator">=></span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">table</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'posts'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="处理死锁" tabindex="-1"><a class="header-anchor" href="#处理死锁"><span>处理死锁</span></a></h4>
<p>传递第二个可选参数给 <code v-pre>transaction</code> 方法，该参数定义在发生死锁时应该重新尝试事务的次数。一旦尝试次数都用尽了，就会抛出一个异常：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">transaction</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">table</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">update</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'votes'</span> <span class="token operator">=></span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">table</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'posts'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="手动操作事务" tabindex="-1"><a class="header-anchor" href="#手动操作事务"><span>手动操作事务</span></a></h4>
<p>如果你想要手动开始一个事务，并且能够完全控制回滚和提交，那么你可以在 <code v-pre>DB</code> facade 上使用 <code v-pre>beginTransaction</code> 方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">beginTransaction</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>可以通过 <code v-pre>rollBack</code> 方法回滚事务：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">rollBack</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>最后记得要通过 <code v-pre>commit</code> 方法提交事务：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">commit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p>{tip} <code v-pre>DB</code> facade 的事务方法也适用于 <a href="https://learnku.com/docs/laravel/5.5/queries" target="_blank" rel="noopener noreferrer">查询语句构造器</a> 和 <a href="https://learnku.com/docs/laravel/5.5/eloquent" target="_blank" rel="noopener noreferrer">Eloquent ORM</a> 的事务。</p>
</blockquote>
<h2 id="译者署名" tabindex="-1"><a class="header-anchor" href="#译者署名"><span>译者署名</span></a></h2>
<table>
<thead>
<tr>
<th>用户名</th>
<th>头像</th>
<th>职能</th>
<th>签名</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://learnku.com/users/15752" target="_blank" rel="noopener noreferrer">@孤雪飘寒</a></td>
<td><img src="https://cdn.learnku.com/uploads/avatars/15752_1493141445.jpeg" alt="15752_1493141445.jpeg"></td>
<td>翻译</td>
<td>全桟工程师，<a href="https://github.com/piaohan" target="_blank" rel="noopener noreferrer">Github</a>，<a href="http://blog.csdn.net/msmile_my" target="_blank" rel="noopener noreferrer">CSDN</a></td>
</tr>
<tr>
<td><a href="https://learnku.com/users/5350" target="_blank" rel="noopener noreferrer">@JokerLinly</a></td>
<td><img src="https://cdn.learnku.com/uploads/avatars/5350_1481857380.jpg" alt="5350_1481857380.jpg"></td>
<td>Review</td>
<td>Stay Hungry. Stay Foolish.</td>
</tr>
</tbody>
</table>
<hr>
<blockquote>
<p>{note} 欢迎任何形式的转载，但请务必注明出处，尊重他人劳动共创开源社区。</p>
<p>转载请注明：本文档由 Laravel China 社区 <a href="https://laravel-china.org/" target="_blank" rel="noopener noreferrer">laravel-china.org</a> 组织翻译，详见 <a href="https://learnku.com/laravel/t/5756/laravel-55-document-translation-call-come-and-join-the-translation" target="_blank" rel="noopener noreferrer">翻译召集帖</a>。</p>
<p>文档永久地址： <a href="https://learnku.com/docs/laravel" target="_blank" rel="noopener noreferrer">《Laravel 中文文档》</a></p>
</blockquote>
</div></template>


